/**
 * 函数防抖: 在事件被触发n秒后再执行回调，如果在这n秒内又被触发，则重新计时
 * @param func 是用户传入需要防抖的函数
 * @param delay 延迟/等待时间
 * @return 返回执行函数
 * eg. 像仿百度搜索，就应该用防抖，当我连续不断输入时，不会发送请求；当我一段时间内不输入了，才会发送一次请求；如果小于这段时间继续输入的话，时间会重新计算，也不会发送请求。
 * 适用场景：按钮提交场景：防止多次提交按钮，只执行最后提交的一次 服务端验证场景：表单验证需要服务端配合，只执行一段连续的输入事件的最后一次，还有搜索联想词功能类似
 */
export const $debounce = (func: any, delay = 1000) => {
  // 1.缓存一个定时器id
  let timerId: number | null = null
  // 2.返回每次用户实际调用的防抖函数
  return function (...args: any) {
    // 3.如果已经设定过定时器了就清空上一次的定时器
    timerId && window.clearTimeout(timerId)
    // 4.开始一个新的定时器，延迟执行用户传入的方法
    timerId = window.setTimeout(() => {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      // 4.1.执行传过来的函数体
      func.apply(this, args)
      // 4.2.清除定时器id
      timerId = null
    }, delay)
  }
}
